﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LibNiconico.NiconicoApi.Internal;
using LibNiconico.NiconicoApi.Lives;
using LibNiconico.NiconicoApi.Utils;
using LibNiconico.NiconicoApi.Lives.WatchPage;
using LibNiconico.NiconicoApi.Lives.Constant;
using LibNiconico.NiconicoApi.Internal.Http;
using LibNiconico.NiconicoApi.PlayerStatus;
using LibNiconico.NiconicoApi.Lives.Comments;
using LibNiconico.NiconicoApi.HeartBeat;
using System.Threading;
using LibNiconico.NiconicoApi.Lives.Broadcast;
using LibNiconico.NiconicoApi.Lives.PublishStatus;


namespace LibNiconico.NiconicoApi.Lives
{
    /// <summary>
    /// ニコニコ生放送APIヘルパー
    /// </summary>
    public sealed class NicoLiveApiHelper:NicoApiHelperBase
    {
        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="auth"></param>
        /// <param name="careateInfo"></param>
        internal NicoLiveApiHelper(NiconicoAuth auth, NiconicoApiInfoGetCreateInfo careateInfo) : base(auth, careateInfo) { }


        /// <summary>
        /// 非同期に生放送に接続
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<NicoLiveConnectionResponse> ConnectLiveAsync(string id)
        {
            var synchronizationContext = SynchronizationContext.Current;


            var playerStatusResponse = await GetPlayerStatusAsync(id).ConfigureAwait(false);
            

            return new NicoLiveConnectionResponse(

                    playerStatusResponse.Succeed,

                    playerStatusResponse,


                    CreateCommentClient(playerStatusResponse.PlayerStatus, synchronizationContext),

                    new NiconicoHeartBeatClient(NicoLiveConstant.NICOLIVE_URL, id, this.Auth)
                );
        }

        /// <summary>
        /// 非同期にプレイヤーステータスを取得
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<NicoGetPlayerStatusResponse> GetPlayerStatusAsync(string id)
        {
            return await GetPlayerStatusAsync(new NicoGetPlayerStatusQueryInfo(id)).ConfigureAwait(false);
        }

        /// <summary>
        /// 非同期にプレイヤーステータスを取得
        /// </summary>
        /// <param name="queryInfo"></param>
        /// <returns></returns>
        internal async Task<NicoGetPlayerStatusResponse> GetPlayerStatusAsync(NicoGetPlayerStatusQueryInfo queryInfo)
        {
            using (var api = new NiconicoInfoGetApiXmlImpl(NicoLiveConstant.NICOLIVE_URL,CreateMostLoginApiHttpClient()))
            {
                
                return  NicoGetPlayerStatusResponse.Parse( (await api.GetAsync( queryInfo).ConfigureAwait(false)).Content);
            }
        }


        /// <summary>
        /// 非同期に視聴ページ情報を取得
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        internal async Task<NicoLiveWatchPageResponse> GetWatchPageAsync(string id)
        {
            return await GetWatchPageAsync(new NicoLiveGetWatchPageQueryInfo(id)).ConfigureAwait(false);
        }

        /// <summary>
        /// 非同期に視聴ページ情報を取得
        /// </summary>
        /// <param name="queryInfo"></param>
        /// <returns></returns>
        internal async Task<NicoLiveWatchPageResponse> GetWatchPageAsync(NicoLiveGetWatchPageQueryInfo queryInfo)
        {
            using (var api = new NiconicoInfoGetApiCookieImpl(NicoLiveConstant.NICOLIVE_URL, CreateMostLoginApiHttpClient()))
            {
                return NicoLiveWatchPageResponse.Parse( (await api.GetAsync(queryInfo).ConfigureAwait(false)).Content);
            }
        }

        internal INicoLiveCommentClient CreateCommentClient(NicoPlayerStatus playerStatus,SynchronizationContext synchronizationContext)
        {
            var commentClient = new NicoLiveCommentClient(this.Auth, NicoLiveCommentConnectionInfo.Create(playerStatus, null), new NiconicoApiInfoGetCreateInfo(), synchronizationContext, true);

            return commentClient;
        }



    }


    
}
